package com.bestcem.xm.ticket.dao;

import com.bestcem.xm.ticket.controller.param.ExportTicketParam;
import com.bestcem.xm.ticket.controller.v2.param.WeChatTicketSearchParam;
import com.bestcem.xm.ticket.dao.dto.TicketInfo;
import com.bestcem.xm.ticket.entity.mongo.Ticket;
import com.bestcem.xm.ticket.enums.TicketStatusEnum;
import com.bestcem.xm.ticket.service.dto.DatetimeFilter;
import com.bestcem.xm.ticket.service.dto.PageDTO;
import com.bestcem.xm.ticket.service.dto.RegionFilter;
import com.bestcem.xm.ticket.service.dto.dashboard.DateTypeCountDTO;
import com.bestcem.xm.ticket.service.dto.dashboard.StatusCountDTO;

import java.time.LocalDateTime;
import java.util.List;

/**
 * mongo DS_TICKET_TICKET 相关DAO层方法
 *
 * @author XiaoYunSong <ys.xiao@idiaoyan.com>
 * @version v1.0
 * @date 2021/8/11 16:02
 */
public interface TicketDao {

    /**
     * 根据id查询 Ticket
     *
     * @param id Ticket
     * @return Ticket 信息
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/11 15:36
     */
    Ticket findById(String id);

    /**
     * 根据configId查询 Ticket
     *
     * @param configId Ticket
     * @return Ticket 信息
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/11 15:36
     * @deprecated 220114时, 没人使用这个方法, 就不写实现了
     */
    @Deprecated
    Ticket findByConfigId(String configId);

    /**
     * 方法描述:根据行动规则查询工单
     *
     * @param configId 行动规则配置id
     * @return List<Ticket>
     * @version v1.0
     * @author gy.liu
     * @date 2021/10/28
     */
    List<Ticket> findTicketsByConfigId(String configId);

    /**
     * 根据id和status查询 Ticket
     *
     * @param id Ticket
     * @return Ticket 信息
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/11 15:36
     */
    Ticket findDeletedById(String id);


    /**
     * 保存 Ticket 信息
     *
     * @param entity 要保存的ticketRecord
     * @return 保存后的 Ticket 信息
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/11 15:58
     */
    Ticket saveTicket(Ticket entity);


    /**
     * 使用save修改ticket所有字段
     *
     * @param entity 实体中必须有id字段
     * @return
     */
    Ticket overrideUpdateTicket(Ticket entity);

    /**
     * 查询公司下所有绑定了工单的问卷项目id
     *
     * @param orgId 公司id
     * @return 对应公司下所有绑定了工单的问卷项目id
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/16 15:06
     * @deprecated 220114时, 没人使用这个方法, 就不写实现了
     */
    @Deprecated
    List<String> findOrgAllSurvey(String orgId);


    /**
     * 根据问卷Id查询工单
     *
     * @param surveyId 问卷id
     * @return 工单list
     */
    List<Ticket> findBySurveyId(String surveyId);


    /**
     * 根据问卷Id统计工单
     *
     * @param surveyId 问卷id
     * @return 工单数量
     */
    long countBySurveyId(String surveyId);

    /**
     * 根据问卷id查询最新工单
     *
     * @param surveyId
     * @return Ticket
     * @version v1.0
     * @author gy.liu
     * @date 2021/10/28
     * @deprecated 220114时, 没人使用这个方法, 就不写实现了
     */
    @Deprecated
    Ticket findLastBySurveyId(String surveyId);

    /**
     * 机构查询
     *
     * @param orgId
     * @return List<Ticket>
     * @version v1.0
     * @author gy.liu
     * @date 2021/10/22
     */
    List<String> findByOrgId(String orgId);

    /**
     * 找到该公司下该用户跟进的下一个工单
     *
     * @param id     ticket的id
     * @param orgId  公司id
     * @param userId 用户id
     * @return 下一个工单
     * @author @author zq.ding <zq.ding@idiaoyan.com>
     * @date 2021/8/16 14:23
     */
    Ticket findNext(String id, String orgId, String userId);

    /**
     * 工单连表查询工单记录
     *
     * @param id
     * @return List<Ticket>
     * @version v1.0
     * @author gy.liu
     * @date 2021/8/20
     */
    List<TicketInfo> lookUpTicketRecord(String id);

    /**
     * 更新工单状态
     *
     * @param id     ticket的id
     * @param status 传入的状态
     * @return 更新结果
     * @author zq.ding <zq.ding@idiaoyan.com>
     * @date 2021/8/20 15:04
     */
    boolean updateStatus(String id, TicketStatusEnum status);

    /**
     * 根据传入的参数查询工单列表,一般会做后续处理
     * !!!注意, 改了这个方法, 要联动修改仪表盘的查询方法
     * {@link TicketDao#aggregateStatusCount}
     *
     * @param param 传入的参数
     * @return 根据入参返回的list
     * @author zq.ding <zq.ding@idiaoyan.com>
     * @date 2021/8/26 20:25
     * @deprecated 导出用 {@link TicketDao#listExportTicket(ExportTicketParam) } / 分页用 {@link TicketDao#pageTicket(ExportTicketParam)}
     */
    @Deprecated
    PageDTO<Ticket> newSearch(ExportTicketParam param);

    /**
     * 获取工单仪表盘数据
     * !!!注意, 改了这个方法, 要联动修改工单列表的查询方法
     * {@link TicketDao#newSearch}
     *
     * @param regionFilter   工单图表统计 公司/区域 统计参数
     * @param datetimeFilter 工单图表统计 时间 统计参数
     * @return 仪表盘数据
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/27 11:17
     */
    List<StatusCountDTO> aggregateStatusCount(RegionFilter regionFilter, DatetimeFilter datetimeFilter);

    /**
     * 统计工单 hasFollowOverdue 为 true 的数量
     *
     * @param regionFilter   工单图标统计 公司/区域 统计参数
     * @param datetimeFilter 工单图表统计 时间 统计参数
     * @return 数量
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/27 14:10
     */
    Long aggregateTicketFollowOverdueCount(RegionFilter regionFilter, DatetimeFilter datetimeFilter);

    /**
     * 统计工单 hasAuditOverdue 为 true 的数量
     *
     * @param regionFilter   工单图标统计 公司/区域 统计参数
     * @param datetimeFilter 工单图表统计 时间 统计参数
     * @return 数量
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/27 14:10
     */
    Long aggregateTicketAuditOverdueCount(RegionFilter regionFilter, DatetimeFilter datetimeFilter);

    /**
     * 对工单数量按照天进行分割统计
     *
     * @param regionFilter 工单图标统计 公司/区域 统计参数
     * @param startTime    开始时间 (注意,传北京时间)
     * @param endTime      结束时间 (注意,传北京时间)
     * @return 统计结果
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/8/27 14:51
     */
    List<DateTypeCountDTO> aggregateTicketCount(RegionFilter regionFilter, LocalDateTime startTime, LocalDateTime endTime);

    /**
     * 根据答卷号码查询工单
     *
     * @param seq 答卷编号
     * @return List<Ticket>
     * @author jy.zhao
     * @date 2021/9/16 10:53
     **/
    List<Ticket> findBySeq(Integer seq);

    /**
     * 更新工单状态
     *
     * @param id       ticket的id
     * @param memberId 联系人id
     * @return 更新结果
     * @author jy.zhao
     * @date 2021/8/20 15:04
     */
    void updateTicketMemberId(String id, String memberId);

    /**
     * 更新工单记录编号
     *
     * @param ticket
     * @return UpdateResult
     * @version v1.0
     * @author gy.liu
     * @date 2021/10/19
     */
    void updateTicketRecordId(Ticket ticket);

    /**
     * 行业sample保存工单
     *
     * @param entity
     * @return Ticket
     * @version v1.0
     * @author gy.liu
     * @date 2021/10/19
     */
    Ticket saveTicketCopy(Ticket entity);

    /**
     * 根据导出参数获取导出的工单数据
     * !!!注意, 改了这个方法, 要联动修改仪表盘的查询方法, 要保证导出的 工单/预警 数量与仪表盘的数量显示一致
     * {@link TicketDao#aggregateStatusCount}
     *
     * @param param 传入的参数
     * @return 根据入参返回的list
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/11/17 15:23
     */
    List<Ticket> listExportTicket(ExportTicketParam param);

    /**
     * 根据导出参数获取分页查询的工单数据
     * !!!注意, 改了这个方法, 要联动修改仪表盘的查询方法, 要保证分页查询的 工单/预警 total 与仪表盘的数量显示一致
     * {@link TicketDao#aggregateStatusCount}
     *
     * @param param 传入的参数
     * @return 根据入参返回的list
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/11/17 15:23
     */
    PageDTO<Ticket> pageTicket(ExportTicketParam param);

    /**
     * 企业微信小程序定制版-根据参数获取分页搜索工单
     *
     * @param param 传入的参数
     * @return 根据入参返回的list
     * @author XiaoYunSong <ys.xiao@idiaoyan.com>
     * @date 2021/12/17 16:55
     */
    PageDTO<Ticket> wechatPageTicket(WeChatTicketSearchParam param);
}
